#ifndef NIXONBOT_CORE_BNCS_PROTOCOL_MESSAGE_H_
#define NIXONBOT_CORE_BNCS_PROTOCOL_MESSAGE_H_

#include <QtCore>

namespace nixonbot {
namespace core {
namespace bncs {
namespace protocol {

class BncsMessage
{
public:
	/* Reads a raw null-terminated string from the data stream.
	 * The BNCS protocol sends strings in this format. */
	static QByteArray readStringFrom(QDataStream& ds);
	
	/* Writes a Qt string (as a null-terminated byte array) to
	 * the data stream according to the BNCS protocol. */
	static void writeStringTo(QDataStream& ds, QByteArray ba);
	
	/* Decodes a BNCS "statstring", used by some BNCS
	 * messages. */
	static QVarLengthArray<quint8> decodeStatString(QVarLengthArray<quint8> coded);

	/* Encodes a BNCS "statstring", used by some BNCS
	 * messages. */
	static QVarLengthArray<quint8> encodeStatString(QVarLengthArray<quint8> plain);

public:
	virtual ~Message() = 0;

	/* Returns a reference to a new, default-constructed object of the
	 * same type as this object, stored on the heap. */
	virtual Message* create() = 0;
	
	/* Returns the packed ID of this message. */
	virtual int id() = 0;
	
	/* Returns the size (in bytes) of this message. */
	virtual int size() = 0;
	
	/* Deserializes this packet from the data stream, assuming the packet
	 * follows the BNCS protocol. */
	friend QDataStream& operator>> (QDataStream& in, Message& data);
	
	/* Serializes this packet to the data stream using the BNCS protocol. */
	friend QDataStream& operator<< (QDataStream& out, const Message& data);

protected:
	/* The actual implementation of the operator>> above.
	 * This must be implemented according to the BNCS protocol
	 * specification by every derived class. */
	virtual void readFrom(QDataStream& ds) = 0;
	
	/* The actual implementation of the operator<< above.
	 * This must be implemented according to the BNCS protocol
	 * specification by every derived class. */
	virtual void writeTo(QDataStream& ds) = 0;
};

}
}
}
}

#endif /* NIXONBOT_CORE_BNCS_PROTOCOL_MESSAGE_H_ */
